<?php


namespace paper\file;


use paper\exception\BaseException;

class Image
{

    const TYPE_GIF = 1;
    const TYPE_JPG = 2;
    const TYPE_PNG = 3;
    const TYPE_BMP = 6;
    const TYPE_WEBP = 25;


    //常量，标识缩略图等比例缩放类型
    const THUMB_SCALING = 1;
    //常量，标识缩略图缩放后填充类型
    const THUMB_FILLED = 2;
    //常量，标识缩略图居中裁剪类型
    const THUMB_CENTER = 3;
    //常量，标识缩略图左上角裁剪类型
    const THUMB_NORTHWEST = 4;
    //常量，标识缩略图右下角裁剪类型
    const THUMB_SOUTHEAST = 5;
    //常量，标识缩略图固定尺寸缩放类型
    const THUMB_FIXED = 6;

    private $fileName; //文件的路径
    private $image;    //生成的图像资源
    private $type;     //图像类型
    private $mime;     //图像类型
    private $quality = 75;  //图像质量

//        1 => 'GIF',
//        2 => JPG,
//3 => PNG,4 => SWF,5 => PSD,6 => BMP,7 => TIFF(intel byte order),8 => TIFF(motorola byte order),9 => JPC,10 => JP2,11 => JPX,12 => JB2,13 => SWC,14 => IFF,15 => WBMP,16 =>XBM]
    /**
     * @var mixed
     */
    private $width;
    /**
     * @var mixed
     */
    private $height;

    /**
     * Image constructor.
     * @param $image
     * @throws BaseException
     */
    public function __construct($image)
    {
        $this->fileName = $image;
        $info           = getimageSize($this->fileName);//获取图片的基本信息
        $this->width    = $info[0];//获取宽度
        $this->height   = $info[1];//获取高度
        $this->type     = $info[2];
        $this->mime     = $info['mime'];

        switch ($this->type) {
            case self::TYPE_PNG:
                $this->image = imagecreatefrompng($this->fileName);
                break;
            case self::TYPE_JPG:
                $this->image = imagecreatefromjpeg($this->fileName);
                break;
            case self::TYPE_GIF:
                $this->image = imagecreatefromgif($this->fileName);
                break;
            case self::TYPE_WEBP:
                $this->image = imagecreatefromwebp($this->fileName);
                break;
            default:
                throw new BaseException("error type!");
        }
    }

    /**
     * @return string
     */
    public function getMime()
    {
        return $this->mime;
    }

    public function getExtension()
    {
        return image_type_to_extension($this->type);
    }

    /**
     * @param $image
     * @return static
     * @throws BaseException
     */
    public static function open($image)
    {
        return new static($image);
    }

    /**
     * @param mixed $quality
     * @return Image
     */
    public function setQuality(int $quality = 75)
    {
        $this->quality = $quality;
        return $this;
    }


    public function save($path)
    {
        // 输出图像（根据源图像的类型，输出为对应的类型）
        // $picInfo  = pathinfo($this->image);//解析源图像的名字和路径信息
        // $savePath = $savePath . "/" . date("Ymd") . "/" . $this->pre . $picInfo["basename"];
        switch ($this->type) {
            case self::TYPE_GIF:
                imagegif($this->image, $path);
                break;
            case self::TYPE_PNG:
                imagepng($this->image, $path);
                break;
            case self::TYPE_JPG:
                imagejpeg($this->image, $path, $this->quality);
                break;
            case self::TYPE_WEBP:
                imagewebp($this->image, $path);
                break;
        }
        //释放图片资源
        imagedestroy($this->image);
    }

    /**
     * @return mixed
     */
    public function getWidth()
    {
        return $this->width;
    }

    /**
     * @return mixed
     */
    public function getHeight()
    {
        return $this->height;
    }

    public function thumb($maxWidth, $maxHeight, $type = self::THUMB_SCALING)
    {
        if ($this->width <= $maxWidth && $this->height <= $maxHeight) {
            return $this;
        }

        //计算缩放比例
        $widthRatio   = $maxWidth / $this->width;     //缩小后宽度与原宽度之比
        $heightRation = $maxHeight / $this->height;   //缩小后高度与原高度之比
        $srcX         = 0;
        $srcY         = 0;

        if ($type == self::THUMB_SCALING) { //等比例缩放
            //那个最小用哪个
            $ration = $widthRatio > $heightRation ? $heightRation : $widthRatio;
            //计算出缩放后的尺寸(向下取整)
            $newWidth  = floor($this->width * $ration);
            $newHeight = floor($this->height * $ration);

        } elseif ($type == self::THUMB_FILLED) { //缩放并且填充到全部区域（可能会被裁剪）
            //计算出缩放后的尺寸(向下取整)
            $newWidth  = $maxWidth;
            $newHeight = $maxHeight;
            if ($widthRatio > $heightRation) {
                $srcY = ($this->height * $widthRatio - $maxHeight) / 2;
            } else {
                $srcX = ($this->width * $heightRation - $maxWidth) / 2;
            }
        } else {  //直接缩放 不考虑比例
            $newWidth  = $maxWidth;
            $newHeight = $maxHeight;
        }
        //创建一个新的图像源（目标图像）
        $newImage = imagecreatetruecolor($newWidth, $newHeight);
        //透明背景变黑处理
        $color = imagecolorallocate($newImage, 255, 255, 255);
        //设置透明
        imagecolortransparent($newImage, $color);
        imagefill($newImage, 0, 0, $color);
        //执行等比缩放
        imagecopyresampled($newImage, $this->image, 0, 0, $srcX, $srcY,
            $newWidth, $newHeight, $this->width, $this->height);
        imagedestroy($this->image);

        $this->image  = $newImage;
        $this->width  = $newWidth;
        $this->height = $newHeight;

        return $this;
    }
}